`timescale 1ns / 1ps
module CPU (
    input clk,
    input rst_n,
    input step_mode,//单步模式
    input step,//单步信号
    input load_mode_en,//下载模式使能信号
    input load_we,//下载模式使能信号
    input [7:0] load_addr,//下载模式地址
    input [15:0] load_datain,//下载模式数据
    output step_done,//单步完成信号c2
    output  [15:0] ACC_data, // 16-bit output for ACC data
    output  [15:0] MBR_data, // 16-bit output for MBR data
    output  [7:0] MAR_data,  // 8-bit output for MAR data
    output  [7:0] PC_data,  // 8-bit output for MAR data
    output  [15:0] AX_data,  // 16-bit output for AX data
    output  [15:0] BX_data,  // 16-bit output for BX data
    output  [15:0] CX_data,  // 16-bit output for CX data
    output  [15:0] DX_data,  // 16-bit output for DX data
    output  [7:0] SP_data,  // 8-bit output for SP data
    output  [15:0] BR_data,  // 16-bit output for BR data
    output  [15:0] MR_data,   // 16-bit output for MR data
    output  [15:0] IR_data // 16-bit output for IR data
    

);

//CU
    wire [47:0] c;//控制信号
    wire [15:0] IR_2_CU;
    wire [7:0] FLAG_2_CU;
    assign step_done = c[2];//单步完成信号c2

    CU CU_inst (
        .IR_input(IR_2_CU),
        .FLAG_input(FLAG_2_CU),
        .clk(clk),
        .rst_n(rst_n),
        .control_signal(c),
        .step_mode(step_mode),//单步模式
        .step(step),//单步信号
        .load_mode_en(load_mode_en)//下载模式使能信号

    );

//MEMORY
    wire [15:0] data_2_MEM;
    wire [7:0] Addr_2_MEM;
    wire [15:0] MEM_2_MBR;
    wire MEM_we;
    MEM MEM_inst(
        .clk(clk),
        .write_en(MEM_we),//MEMORY<=MBR c34
        .MBR_in(data_2_MEM),//16位数据输入
        .MAR_in(Addr_2_MEM),//8位地址输入
        .data_2_MBR(MEM_2_MBR)////16位数据输出
    );
// 数据总线   
    wire [15:0] data_bus;
//MAR
wire [7:0] MAR_2_MEM;
    MAR MAR_inst(
            .clk(clk),
            .data_in_en(c[23]),//MAR_in
            .data_out_en(1'b0),
            .data_bus(data_bus),
            .rst_n(rst_n),
            .data_2_MEMORY(MAR_2_MEM)//output to MEMORY
        );
//MBR
wire [15:0] MBR_2_MEM;
    MBR MBR_inst (
        .clk(clk),
        .data_in_en(c[24]),//MBR_in
        .data_out_en(c[25]),//MBR_out
        .imm_out_en(c[27]),//MBR#IMM_out [9:0]立即数
        .imm_out_en_7bit(c[35]),//MBR#IMM_out [6:0]立即数
        .data_bus(data_bus),
        .rst_n(rst_n),
        .read_form_MEM_en(c[26]),//MBR<=MEMORY  c26
        .data_form_MRMORY(MEM_2_MBR),
        .data_2_MEM(MBR_2_MEM)
    );

//下载模式MUX
//下载模式MUX
MEM_MUX MEM_MUX_inst (
    .load_mode_en(load_mode_en),
    .load_addr(load_addr),
    .load_datain(load_datain),
    .load_we(load_we), 
    .cpu_addr(MAR_2_MEM),
    .cpu_datain(MBR_2_MEM),
    .cpu_we(c[34]), // MEM write enable signal
    .mem_we(MEM_we),
    .mem_addr(Addr_2_MEM),
    .mem_datain(data_2_MEM)
);


//PC

    PC PC_inst (
        .clk(clk),
        .data_in_en(c[4]),//PC_in
        .data_out_en(c[5]),//PC_out
        .data_bus(data_bus),
        .rst_n(rst_n),
        .PC_ADD_1(c[2]||c[3]) // PC<=PC+1控制信号  CAR<=0 同时c2
    );
//IR

    IR IR_inst (
        .clk(clk),
        .data_in_en(c[33]),//IR_in
        .data_out_en(1'b0),//IR_out
        .data_bus(data_bus),
        .rst_n(rst_n),
        .IR_reg(IR_2_CU) // output to CU作为输入
    );

//ACC
    wire ACC_in_en;
    wire ACC_out_en;
    wire [15:0] ALU_2_ACC;
    wire [15:0] ACC_2_ALU;

    ACC ACC_inst (
        .clk(clk),
        .data_in_en(ACC_in_en),
        .data_out_en(ACC_out_en),
        .data_bus(data_bus),
        .rst_n(rst_n),
        .ALU_2_ACC_en(c[16]),//ACC<=ALU控制信号c16
        .ALU_in(ALU_2_ACC),//input from ALU的输出
        .data_2_ALU(ACC_2_ALU)//output to ALU作为输入
    );
//BR
    wire BR_in_en;
    wire BR_out_en;
    wire [15:0] BR_2_ALU;

    BR BR_inst (
        .clk(clk),
        .data_in_en(BR_in_en),
        .data_out_en(BR_out_en),
        .data_bus(data_bus),
        .rst_n(rst_n),
        .data_2_ALU(BR_2_ALU) // output to ALU作为输入
    );
//MR
    wire MR_in_en;
    wire MR_out_en;
    wire [15:0] ALU_2_MR;

    MR MR_inst (
        .clk(clk),
        .data_in_en(MR_in_en),
        .data_out_en(MR_out_en),
        .data_bus(data_bus),
        .rst_n(rst_n),
        .ALU_2_MR_en(c[32]), // MR<=ALU_MR控制信号c32
        .ALU_MR_in(ALU_2_MR) // input from ALU的输出
    );
//ALU

    ALU ALU_inst (
        .ACC_in(ACC_2_ALU),
        .BR_in(BR_2_ALU),
        .ALU_control(c[15:8]),//ALU控制信号c8-c15
        .clk(clk),
        .rst_n(rst_n),
        .ALU_out(ALU_2_ACC),
        .MR_out(ALU_2_MR),
        .FLAG(FLAG_2_CU)
    );
//AX
wire AX_in_en;
wire AX_out_en;
register AX_inst (
    .clk(clk),
    .data_in_en(AX_in_en), // AX_in
    .data_out_en(AX_out_en), // AX_out
    .data_bus(data_bus),
    .rst_n(rst_n)
);
//BX
wire BX_in_en;
wire BX_out_en;
register BX_inst (
    .clk(clk),
    .data_in_en(BX_in_en), // BX_in
    .data_out_en(BX_out_en), // BX_out
    .data_bus(data_bus),
    .rst_n(rst_n)
);

//CX
wire CX_in_en;
wire CX_out_en;
register CX_inst (
    .clk(clk),
    .data_in_en(CX_in_en), // CX_in
    .data_out_en(CX_out_en), // CX_out
    .data_bus(data_bus),
    .rst_n(rst_n)
);

//DX
wire DX_in_en;
wire DX_out_en;
register DX_inst (
    .clk(clk),
    .data_in_en(DX_in_en), // DX_in
    .data_out_en(DX_out_en), // DX_out
    .data_bus(data_bus),
    .rst_n(rst_n)
);
//SP
wire SP_in_en;
wire SP_out_en;

SP SP_inst (
    .clk(clk),
    .data_in_en(SP_in_en), // SP_in
    .data_out_en(SP_out_en), // SP_out
    .data_bus(data_bus),
    .rst_n(rst_n),
    .SP_ADD_1(c[20]), // SP<=SP+1控制信号
    .SP_SUB_1(c[19])  // SP<=SP-1控制信号
);
//BUS_EN_DECODE
    wire [2:0] Rx_in_index;
    wire [2:0] Rx_out_index;

    BUS_EN_DECODE BUS_EN_DECODE_inst (
        .in_ACC_in_en(c[17]),
        .in_ACC_out_en(c[18]),

        .in_BR_in_en(c[6]),
        .in_BR_out_en(c[7]),

        .in_MR_in_en(c[30]),
        .in_MR_out_en(c[31]),

        .in_Rx_in_en(c[28]),
        .in_Rx_out_en(c[29]),

        .in_SP_in_en(c[21]),
        .in_SP_out_en(c[22]),

        .out_ACC_in_en(ACC_in_en),
        .out_ACC_out_en(ACC_out_en),

        .out_BR_in_en(BR_in_en),
        .out_BR_out_en(BR_out_en),

        .out_MR_in_en(MR_in_en),
        .out_MR_out_en(MR_out_en),

        // Unused signals
        .out_AX_in_en(AX_in_en), 
        .out_AX_out_en(AX_out_en), 
        .out_BX_in_en(BX_in_en), 
        .out_BX_out_en(BX_out_en), 
        .out_CX_in_en(CX_in_en), 
        .out_CX_out_en(CX_out_en), 
        .out_DX_in_en(DX_in_en), 
        .out_DX_out_en(DX_out_en),

        .out_SP_in_en(SP_in_en),
        .out_SP_out_en(SP_out_en),

        .Rx_in_index(IR_2_CU[9:7]),//[9:7]输入 [6:4]输出
        .Rx_out_index(IR_2_CU[6:4])
    );
assign ACC_data = ACC_inst.data_reg;
assign MBR_data = MBR_inst.data_reg;
assign MAR_data = MAR_inst.data_reg;
assign AX_data = AX_inst.data_reg;
assign BX_data = BX_inst.data_reg;
assign CX_data = CX_inst.data_reg;
assign DX_data = DX_inst.data_reg;
assign SP_data = SP_inst.data_reg;
assign BR_data = BR_inst.data_reg;
assign MR_data = MR_inst.data_reg;
assign PC_data = PC_inst.data_reg;   
assign IR_data = IR_inst.data_reg;
endmodule